package com.mk.service.platform;

import act.apidoc.Description;
import act.controller.Controller;
import act.inject.DefaultValue;
import act.validation.NotBlank;
import cn.hutool.core.date.DateUtil;
import com.mk.domain.CpRoleUser;
import com.mk.domain.CpSsorole;
import com.mk.domain.CpUser;
import com.mk.enums.ErrorCode;
import com.mk.enums.GlobalValues;
import com.mk.exception.UserException;
import com.mk.interceptor.ITranslate;
import com.mk.util.EncyUtils;
import com.mk.util.Redis;
import com.mk.util.S2;
import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.engine.PageQuery;
import org.osgl.mvc.annotation.*;
import org.osgl.util.S;

import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import java.util.*;

@Controller("user")
@SuppressWarnings("unused")
public class CpUserService extends BasePlatformService {

    @Inject
    private CpUser.Mapper cpUserMapper;
    @Inject
    private CpSsorole.Mapper cpSsoroleMapper;

    @Inject
    private CpRoleUser.Mapper cpRoleUserMapper;

    @Description("*通用-员工-查询当前用户所在机构的所有员工列表(已实现)")
    @With(ILogin.class)
    @GetAction("pageUsers.json")
    public PageQuery<CpUser> cpUserList(
        @Description("筛选条件-姓名") String realname,
        @Description("筛选条件-手机号") String phone,
        @Description("获取公司员工时传入公司id") String coid,
        @Description("获取仓库员工时传入") String cdid,
        @Description("当前第几页") @NotNull Integer currentPage,
        @Description("每页多少条") @DefaultValue("15") Integer pageSize

    ) {
        PageQuery<CpUser> query = new PageQuery<>();
        query.setPageSize(pageSize);
        query.setPageNumber(currentPage);
        Map<String, Object> map = new HashMap<>();
        map.put("realname", realname);
        map.put("phone", phone);
        map.put("usertype", GlobalValues.USERTYPE_0.value());
        query.setParas(map);
        //此处的sql是三个sql
        cpUserMapper.getSQLManager().pageQuery("CpUser.select_list_usertype0", CpUser.class, query);
        return query;
    }


    @Description("*通用-员工-查询当前用户所在机构的所有员工列表(已实现)")
    @With(ILogin.class)
    @GetAction("getFanceList.json")
    public PageQuery<CpUser> getFanceList(
        @Description("筛选条件-姓名") String realname,
        @Description("筛选条件-手机号") String phone,
        @Description("当前第几页") @NotNull Integer currentPage,
        @Description("每页多少条") @DefaultValue("15") Integer pageSize
    ) {
        PageQuery<CpUser> query = new PageQuery<>();
        query.setPageSize(pageSize);
        query.setPageNumber(currentPage);
        Map<String, Object> map = new HashMap<>();
        map.put("realname", realname);
        map.put("phone", phone);
        map.put("usertype", GlobalValues.USERTYPE_1.value());
        query.setParas(map);
        //此处的sql是三个sql
        cpUserMapper.getSQLManager().pageQuery("CpUser.select_list_usertype1", CpUser.class, query);
        return query;
    }


    @Description("*通用-员工-查询当前用户所在机构的所有员工列表(已实现)")
    @With(ILogin.class)
    @GetAction("cpRoleidList.json")
    public CpSsorole cpRoleidList(String userid) {
        CpSsorole cpSsorolePlatform = new CpSsorole();
        List<String> roleids = cpUserMapper.getRoleidList(userid);
        if (roleids != null && roleids.size() > 0) {
            String roleid = roleids.get(0);
            cpSsorolePlatform = cpSsoroleMapper.single(roleid);
        }
        return cpSsorolePlatform;
    }


    @Description("*通用-员工-增加, 返回cpuser成功 其它错误失败")
    @PostAction("add.json")
    @With({ILogin.class, ITranslate.class})
    public CpUser add(@NotNull @Description("用于保存的对象") CpUser cpUser, @Description("角色id") String roleid) {
        validateUser(cpUser, true);
        String pwd = S.isBlank(cpUser.getPassword()) ? GlobalValues.DEFAULT_PASSWORD.value() : cpUser.getPassword();
        cpUser.setPassword(EncyUtils.MD5(pwd));
        String userid = S2.UUID();
        cpUser.setUserid(userid);
        cpUser.setRegtime(DateUtil.now());
        cpUserMapper.insert(cpUser);
        if (S.isNotBlank(roleid)) {
            if (cpUser.getRoleids() != null) {
                cpUser.getRoleids().add(roleid);
            } else {
                List<String> roleids = new ArrayList<>();
                roleids.add(roleid);
                cpUser.setRoleids(roleids);
            }
        }
        saveRole(cpUser);

        return cpUser;
    }

    @Description("*通用-员工-修改, 返回1成功 其它错误失败")
    @PutAction("update.json")
    @With({ILogin.class, ITranslate.class})
    public Integer update(@NotNull @Description("用于修改的对象") CpUser cpUser, @Description("角色id") String roleid) {
        validateUser(cpUser, false);
        int updateCount = cpUserMapper.updateTemplateById(cpUser);
        if (S.isNotBlank(roleid)) {
            if (cpUser.getRoleids() != null) {
                cpUser.getRoleids().add(roleid);
            } else {
                List<String> roleids = new ArrayList<>();
                roleids.add(roleid);
                cpUser.setRoleids(roleids);
            }
        }
        saveRole(cpUser);

        return updateCount;
    }

    @Description("*通用-员工-删除，返回1成功 其它错误失败，逻辑删除")
    @DeleteAction("{userid}/del.json")
    @With({ILogin.class, ITranslate.class})
    public Integer del(@NotBlank @Description("员工ID") String userid) {
        CpUser cpUser = new CpUser();
        cpUser.setUserid(userid);
        cpUserMapper.templateOne(cpUser);

        //验证是否是自己
        validateIsSelf(cpUser);

        //更改状态为冻结
        cpUser.setUserstate(GlobalValues.COMMON_0.value());
        return cpUserMapper.updateById(cpUser);
    }

    @Description("验证是否是自己")
    private void validateIsSelf(CpUser cpUser) {
        UserException.throwIf(me.getUserid().equals(cpUser.getUserid()), ErrorCode.E201011);
    }


    /**
     * 自己修改密码
     */
    @PostAction("updatepwd.json")
    @With({ILogin.class, ITranslate.class})
    @Description("通用-修改密码-通过验证旧密码，从而修改新密码")
    public int updatePwd(
        @NotBlank(message = "没有输入旧密码!") String oldpwd,
        @NotBlank(message = "没有输入新密码!") String newpwd
    ) {

        UserException.throwIf(S.isNotBlank(cpUserMapper.checkUserPwd(me.getUserid(), EncyUtils.MD5(oldpwd))), ErrorCode.E201008);
        return cpUserMapper.resetPwd(me.getUserid(), EncyUtils.MD5(newpwd));
    }

    /**
     * 自己修改密码-通过短信验证码
     */
    @PostAction("updatepwdbymscode.json")
    @With({ILogin.class, ITranslate.class})
    @Description("通用-修改密码-通过短信验证码，从而修改新密码")
    public int updatePwdByMscode(String password,
                                 @NotBlank(message = "没有输入手机验证码") String msgcode
    ) {
        CpUser user = cpUserMapper.single(me.getUserid());
        String cachedCode = Redis.otherDb.getBucket(GlobalValues.SMS_CODE.value() + "-" + user.getPhone(), String.class).get();
        if (S.eq(cachedCode, msgcode)) {
            CpUser cpUser = new CpUser();
            cpUser.setUserid(me.getUserid());
            if (StringUtils.isNotBlank(password)) {
                cpUser.setPassword(EncyUtils.MD5(password));
                return cpUserMapper.updateTemplateById(cpUser);
            } else {
                return 0;
            }
        } else {
            UserException.throwNow(ErrorCode.E201009);
        }
        return 0;
    }


    /**
     * 修改用户信息-通过短信验证码
     */
    @PostAction("updateinfobymscode.json")
    @With({ILogin.class, ITranslate.class})
    @Description("通用-修改用户信息-通过短信验证码")
    public int updateinfobymscode(CpUser user,
                                  @NotBlank(message = "没有输入手机验证码") String msgcode
    ) {
        CpUser userServer = cpUserMapper.single(me.getUserid());
        String cachedCode = Redis.otherDb.getBucket(GlobalValues.SMS_CODE.value() + "-" + userServer.getPhone(), String.class).get();
        if (S.eq(cachedCode, msgcode)) {
            CpUser cpUser = new CpUser();
            cpUser.setUserid(me.getUserid());
            if (StringUtils.isNotBlank(user.getPassword())) {
                cpUser.setPassword(EncyUtils.MD5(user.getPassword()));
            }
            cpUser.setRealname(user.getRealname());
            return cpUserMapper.updateTemplateById(cpUser);
        } else {
            UserException.throwNow(ErrorCode.E201009);
        }
        return 0;
    }


    @Description("管理员帮自己的员工重置密码.暂时不要该功能(已实现)")
    @With({ILogin.class, ITranslate.class})
    @PutAction("resetPwd.json")
    public int resetPwd(
        @Description("重置密码的用户id")
        @NotBlank String userid,
        @Description("要重置的密码")
        @NotBlank String password
    ) {
        return cpUserMapper.resetPwd(userid, EncyUtils.MD5(password));
    }


    //用户增加或修改时验证方法
    private void validateUser(CpUser cpUser, Boolean isAdd) {
        if (S.isBlank(cpUser.getUserstate())) {
            cpUser.setUserstate(GlobalValues.COMMON_1.value());
        }

        CpUser example = new CpUser();
        example.setPhone(cpUser.getPhone());
        example.setUsertype(GlobalValues.USERTYPE_0.value());
        CpUser check;
        List<String> errors = new ArrayList<>();
        try {
            check = cpUserMapper.templateOne(example);
            if ((isAdd && check != null) || (!isAdd && check != null && !Objects.equals(check.getUserid(), cpUser.getUserid()))) {
                errors.add("手机号码重复");
            }
        } catch (Exception e) {
            errors.add("手机号码重复");
        }
        UserException.throwIf(!errors.isEmpty(), String.join(",", errors));
    }

    //用户增加和修改执行完后，保存角色
    private void saveRole(CpUser cpUser) {
        if (cpUser.getRoleids() == null) {
            cpUser.setRoleids(new ArrayList<>());
        }
        cpRoleUserMapper.saveUserRoles(cpUser.getRoleids(), cpUser.getUserid());
    }

    @Description("通过手机号验证用户是否存在")
    public Boolean userExistByPhone(String phoneNum) {
        String t = cpUserMapper.selectUserByPhone(phoneNum);
        return !StringUtils.isNotBlank(t);
    }
}
